"""
@File    :   route_depend.py
@Time    :   2024/03/28 23:35:28
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   路由依赖(用于维持本业务的路由部分整洁)
"""

from typing import Annotated

from fastapi import Depends, File, UploadFile
from sqlalchemy.ext.asyncio import AsyncSession

from src.business.admin.system.oauth2.token.dependencies.no_introduction import (
    GetTenantIdFromAccessTokenDependencies,
    GetUserIdFromAccessTokenDependencies,
    GetUserNameFromAccessTokenDependencies,
)
from src.business.admin.system.settings.service import SystemSettingsService
from src.business.admin.system.user.schemas.out import (
    UserCompleteOutSchema,
    UserSelfAndMenuOutSchema,
)
from src.business.admin.system.user.schemas.validate import (
    UserAssignRoleValidateSchema,
    UserCreateValidateSchema,
    UserDeleteValidateSchema,
    UserListSearchValidateSchema,
    UserResetPasswordValidateSchema,
    UserSelfUpdateAvatarValidateSchema,
    UserSelfUpdateInfoValidateSchema,
    UserSelfUpdatePasswordValidateSchema,
    UserUpdateStatusValidateSchema,
    UserUpdateValidateSchema,
)
from src.business.admin.system.user.service import UserService
from src.dependencies.no_introduction import depend_get_master_db_session
from src.schemas.validate import (
    OrderBySearchValidateSchema,
    PaginationSearchValidateSchema,
)
from src.utils.upload import UploadUtil

from .no_introduction import GetUserIdDependencies


async def route_depend_get_user(
    user_id: Annotated[int, Depends(GetUserIdDependencies.from_query)],
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
) -> UserCompleteOutSchema:
    """查询单个后台用户的路由依赖

    Args:
        user_id (Annotated[int, Depends): 用户ID
        tenant_id: 当前token指向的租户ID
        db_session (Annotated[AsyncSession, Depends): 数据库连接池

    Returns:
        UserCompleteOutSchema: 用户信息
    """
    user: UserCompleteOutSchema = await UserService.get_user_use_id(
        db_session, tenant_id, user_id, raise_disabled_exception=False
    )
    return user


async def route_depend_list_user(
    search_schema: UserListSearchValidateSchema,
    pagination_schema: PaginationSearchValidateSchema,
    order_schema: OrderBySearchValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
) -> tuple[list[UserCompleteOutSchema], int]:
    """查询后台用户列表的路由依赖

    Args:
        search_schema (Annotated[TenantListSearchValidateSchema, Depends): 查询参数
        pagination_schema (Annotated[PaginationSearchValidateSchema, Depends): 分页参数
        order_schema (Annotated[OrderBySearchValidateSchema, Depends): 排序参数
        tenant_id: 当前token指向的租户ID
        db_session (Annotated[AsyncSession, Depends): 数据库连接池

    Returns:
        tuple[list[UserCompleteOutSchema], int]: 查询结果
    """
    # 注解
    search_pagination_result: list[UserCompleteOutSchema]
    search_total: int
    # 列表结果查询
    (
        search_pagination_result,
        search_total,
    ) = await UserService.list_search_user(
        db_session, tenant_id, search_schema, pagination_schema, order_schema
    )
    return search_pagination_result, search_total


async def route_depend_create_user(
    create_schema: UserCreateValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    username: Annotated[
        str, Depends(GetUserNameFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
) -> int:
    """创建后台用户的依赖

    Args:
        create_schema (UserCreateValidateSchema): 创建用户的schema
        tenant_id: 当前token指向的租户ID
        username: 当前token指向的用户名
        db_session: 数据库连接池

    Returns:
        int: 创建的sql的主键ID
    """
    # 创建用户
    created_id = await UserService.create_user(
        db_session, tenant_id, create_schema, creator_username=username
    )
    return created_id


async def route_depend_update_user(
    update_schema: UserUpdateValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    username: Annotated[
        str, Depends(GetUserNameFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
):
    """修改用户的路由依赖

    Args:
        update_schema (TenantUpdateValidateSchema): 修改用户所需的参数
        tenant_id: 当前token指向的租户ID
        username: 当前token指向的用户名
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    """
    # 修改操作
    await UserService.update_user(
        db_session, tenant_id, update_schema, updater_username=username
    )


async def route_depend_update_user_status(
    update_schema: UserUpdateStatusValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    username: Annotated[
        str, Depends(GetUserNameFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
):
    """单独修改用户状态的路由依赖

    Args:
        update_schema (TenantUpdateStatusValidateSchema): 修改用户所需的参数
        tenant_id: 当前token指向的租户ID
        username: 当前token指向的用户名
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    """
    # 修改操作
    await UserService.update_user_status(
        db_session, tenant_id, update_schema, updater_username=username
    )


async def route_depend_delete_user(
    delete_schema: UserDeleteValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
):
    """删除后台的路由依赖

    Args:
        delete_schema (TenantDeleteValidateSchema): 删除租户所需的参数
        tenant_id: 当前token指向的租户ID
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    """
    # 删除操作
    await UserService.delete_user(db_session, tenant_id, delete_schema)


async def route_depend_reset_user_password(
    reset_password_schema: UserResetPasswordValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    username: Annotated[
        str, Depends(GetUserNameFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
):
    """重置后台用户密码的路由依赖

    Args:
        reset_password_schema: 重置后台用户密码所需的参数
        tenant_id: 当前token指向的租户ID
        username: 当前token指向的用户名
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    """
    # 重置密码操作
    await UserService.reset_user_password(
        db_session, tenant_id, reset_password_schema, updater_username=username
    )


async def route_depend_assign_user_role(
    assign_schema: UserAssignRoleValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
):
    """分配后台用户角色的路由依赖

    Args:
        assign_schema: 所需的参数
        tenant_id: 当前token指向的租户ID
        username: 当前token指向的用户名
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    """
    # 分配操作
    await UserService.assign_user_role(db_session, tenant_id, assign_schema)


async def route_depend_get_self_info(
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    self_id: Annotated[int, Depends(GetUserIdFromAccessTokenDependencies.from_header)],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
) -> UserCompleteOutSchema:
    """查询用户自身信息的路由依赖

    Args:
        tenant_id: 当前token指向的租户ID
        self_id (Annotated[int, Depends): 当前token指向的用户ID
        db_session (Annotated[AsyncSession, Depends): 数据库连接池

    Returns:
        UserCompleteOutSchema: 用户自身信息
    """
    user: UserCompleteOutSchema = await UserService.get_user_use_id(
        db_session, tenant_id, self_id
    )
    return user


async def route_depend_get_self_and_menu_info(
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    self_id: Annotated[int, Depends(GetUserIdFromAccessTokenDependencies.from_header)],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
) -> UserSelfAndMenuOutSchema:
    """获取用户自身及其关联菜单的数据的路由依赖

    Args:
        tenant_id (Annotated[ int, Depends): 当前token指向的租户ID
        self_id (Annotated[int, Depends): 当前token指向的用户ID
        db_session (Annotated[AsyncSession, Depends): 数据库连接池

    Returns:
        UserSelfAndMenuOutSchema: 用户自身及其关联菜单的数据
    """
    user_and_menu_info = await UserService.get_user_self_and_menu_info(
        db_session, tenant_id, self_id
    )
    return user_and_menu_info


async def route_depend_update_self_info(
    update_self_schema: UserSelfUpdateInfoValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    self_id: Annotated[int, Depends(GetUserIdFromAccessTokenDependencies.from_header)],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
):
    """用户修改自身信息的路由依赖

    Args:
        update_self_schema: 所需的参数
        tenant_id: 当前token指向的租户ID
        self_id: 当前token指向的用户ID
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    """
    # 修改自身操作
    await UserService.update_self_info(
        db_session, tenant_id, self_id, update_self_schema
    )


async def route_depend_update_self_avatar(
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    self_id: Annotated[int, Depends(GetUserIdFromAccessTokenDependencies.from_header)],
    avatar_blob: Annotated[UploadFile, File(description="头像图片数据")],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
) -> str:
    """用户修改自身头像的路由依赖

    Args:
        tenant_id: 当前token指向的租户ID
        self_id: 当前token指向的用户ID
        avatar_blob: 头像图片数据
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    Return:
        str: 保存的相对路径
    """
    # 获取租户的配置
    tenant_settings = await SystemSettingsService.get_system_settings_use_tenant_id(
        db_session, tenant_id
    )
    # 进行文件大小与文件类型验证并保存
    save_rel_path = await UploadUtil.validate_and_save_upload_file(
        avatar_blob,
        tenant_settings.user_avatar_image_upload_type,
        tenant_settings.user_avatar_image_upload_max_size,
        "avatar_blob",
    )
    # 构建修改所需参数
    update_self_schema = UserSelfUpdateAvatarValidateSchema(avatar=save_rel_path)
    # 修改自身操作
    await UserService.update_self_avatar(
        db_session, tenant_id, self_id, update_self_schema
    )
    return save_rel_path


async def route_depend_update_self_password(
    update_self_schema: UserSelfUpdatePasswordValidateSchema,
    tenant_id: Annotated[
        int, Depends(GetTenantIdFromAccessTokenDependencies.from_header)
    ],
    self_id: Annotated[int, Depends(GetUserIdFromAccessTokenDependencies.from_header)],
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
):
    """用户修改自身密码的路由依赖

    Args:
        update_self_schema: 修改所需的参数
        tenant_id: 当前token指向的租户ID
        self_id: 当前token指向的用户ID
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
    """
    # 修改自身操作
    await UserService.update_self_password(
        db_session, tenant_id, self_id, update_self_schema
    )
